"""
    Controller for plan table. Contains topics and plans transfers tabs.
"""

from turbogears import widgets, expose, validate, redirect, identity
from turbogears.widgets import TextField

from mnemoply import model
from mnemoply.mass_actions import MassAction
from mnemoply.controllers.lookup import LookupController, TableCol, TableLookupDataSource
from mnemoply.controllers.crud import CRUDController, ItemTab, ItemActionsTab1
from mnemoply.widgets import DictionaryField, TopicField, DecimalValidator

class MAClone(MassAction):
    target_class = model.Plan
    name = "clone"
    title = _("Clone")

    def call(self, objs):
        for plan in objs:
            new_plan = model.Plan(name=plan.name, year=plan.year + 1,
                                  abbr=plan.abbr, trend=plan.trend,
                                  lessonDuration=plan.lessonDuration)
            for pt in plan.topics:
                model.PlanTopic(plan=new_plan, topic=pt.topic, hours=pt.hours, ordinal=pt.ordinal)

class TopicsItemTab(ItemTab):
    title = _("Topics")
    name = "topics_tab"
    template = "../plan_topics_tab"

    add_form = widgets.TableForm(fields=[
            TopicField(name="topic_data", label=_("Topic")),
            TextField(name="hours", validator=DecimalValidator(not_empty=True), label="Hours"),
        ],
        submit_text=_("Add"),
        action='add_topic',
    )

    edit_form = widgets.TableForm(fields=[
            widgets.HiddenField(
                name="tid",
            ),
            widgets.TextField(
                name="hours",
                validator=DecimalValidator(not_empty=True),
                label="Hours",
            ),
            TopicField(name="topic_id", label=_("Topic")),

        ],
        submit_text=_("Update"),
        action='edit_topic',
    )

    @identity.require(identity.has_any_permission('dba', 'Topic/edit'))
    @expose(template="genshi:mnemoply.templates.plan_topic_edit")
    def edit_topic_req(self, obj, tid):
        ptopic = model.PlanTopic.get(int(tid))
        assert ptopic.plan == obj

        return dict(form=self.edit_form,
                topic=ptopic,
                values=dict(
                    tid=int(tid),
                    topic_id=ptopic.topic.id,
                    hours=ptopic.hours,
        ))

    @identity.require(identity.has_any_permission('dba', 'Topic/edit'))
    @validate(form=edit_form)
    @expose()
    def edit_topic(self, obj, tid, topic_id, hours, tg_errors=None):
        ptopic = model.PlanTopic.get(int(tid))
        assert ptopic.plan == obj

        if tg_errors:
            return self.edit_topic_req(obj, tid)

        ptopic.topic = model.Topic.get(int(topic_id))
        ptopic.hours = hours

        raise redirect("./")

    @identity.require(identity.has_any_permission('dba', 'Topic/edit'))
    @expose()
    def delete_topic(self, obj, tid):
        tid = int(tid)
        ptopic = model.PlanTopic.get(tid)

        assert ptopic.plan == obj
        ordinal = ptopic.ordinal
        plan = ptopic.plan
        ptopic.destroySelf()

        for topic in model.PlanTopic.selectBy(plan=plan):
            if topic.ordinal > ordinal:
                topic.ordinal -= 1

        raise redirect("./")

    @identity.require(identity.has_any_permission('dba', 'Topic/edit'))
    @expose()
    def up_topic(self, obj, tid):
        topic = model.PlanTopic.get(int(tid))
        assert topic.plan == obj
        if topic.ordinal > 1:
            prev = list(model.PlanTopic.selectBy(plan=topic.plan, ordinal=topic.ordinal - 1))
            if len(prev) > 0:
                prev_topic = prev[0]
                ordinal = topic.ordinal
                topic.ordinal = 0
                prev_topic.ordinal = ordinal
                topic.ordinal = ordinal - 1
            else:
                topic.ordinal -= 1

        raise redirect("./")

    @identity.require(identity.has_any_permission('dba', 'Topic/edit'))
    @expose()
    def down_topic(self, obj, tid):
        topic = model.PlanTopic.get(int(tid))
        assert topic.plan == obj
        max_ordinal = model.PlanTopic.selectBy(plan=topic.plan).max('ordinal')
        if topic.ordinal < max_ordinal:
            next = list(model.PlanTopic.selectBy(plan=topic.plan, ordinal=topic.ordinal + 1))
            if len(next) > 0:
                next_topic = next[0]
                ordinal = topic.ordinal
                topic.ordinal = 0
                next_topic.ordinal = ordinal
                topic.ordinal = ordinal + 1
            else:
                topic.ordinal += 1

        raise redirect("./")

    @identity.require(identity.has_any_permission('dba', 'Topic/edit'))
    @validate(form=add_form)
    @expose()
    def add_topic(self, obj, topic_data, hours, tg_errors=None):
        if tg_errors:
            raise redirect("./")
        if topic_data is not None:
            topic = model.Topic.get(int(topic_data))
            model.PlanTopic(plan=obj, topic=topic, hours=hours)

        raise redirect("./")

class PlanTransferItemTab(ItemTab):
    title = _("Transfers")
    name = "transfers_tab"
    template = "../plan_transfers_tab"

    add_form = widgets.TableForm(fields=[
            DictionaryField(name='plan_id', model_object_name='Plan', not_empty=True, label=_("Plan")),
            TextField(name="comment", label="Comment", value="Comment"),
        ],
        submit_text=_("Add"),
        action='add_plan_transfer',
    )

    @identity.require(identity.has_any_permission('dba', 'PlanTransfer/edit'))
    @validate(form=add_form)
    @expose()
    def add_plan_transfer(self, obj, plan_id, comment):
        next_plan = model.Plan.get(int(plan_id))
        if comment is None:
            model.PlanTransfer(currentPlan=obj, nextPlan=next_plan)
        else:
            model.PlanTransfer(currentPlan=obj, nextPlan=next_plan, comment=comment)
        raise redirect("./")

    @identity.require(identity.has_any_permission('dba', 'PlanTransfer/edit'))
    @expose()
    def delete_plan_transfer(self, obj, id):
        pt = model.PlanTransfer.get(int(id))
        pt.destroySelf()
        raise redirect("./")

class CustomerTariffItemTab(ItemActionsTab1):
    title = _("Customer tariff")
    name = "customer_tariff_tab"
    obj_field="plan_id"
    model_object_child = model.CustomerTariffPlan
    field_object_main = "customerTariff"
    fields=[
            DictionaryField(name='tariff_id', model_object_name='CustomerTariff', not_empty=True, label=_("Customer tariff")),
        ]
    @expose()
    def add_action(self, obj, tariff_id):
        tariff = model.CustomerTariff.get(int(tariff_id))

        model.CustomerTariffPlan(plan=obj, customerTariff=tariff)
        raise redirect("./")

class TeacherTariffItemTab(ItemActionsTab1):
    title = _("Teacher tariff")
    name = "teacher_tariff_tab"
    obj_field="plan_id"
    model_object_child = model.TeacherTariffPlan
    field_object_main = "teacherTariff"
    fields=[
            DictionaryField(name='tariff_id', model_object_name='TeacherTariff', not_empty=True, label=_("Teacher tariff")),
        ]
    
    @expose()
    def add_action(self, obj, tariff_id):
        tariff = model.TeacherTariff.get(int(tariff_id))
        model.TeacherTariffPlan(plan=obj, teacherTariff=tariff)
        raise redirect("./")
    
class PlanController(LookupController, CRUDController):
    model_object = model.Plan
    lookup_columns = [
        TableCol(name='faculty', caption=_("Faculty")),
        TableCol(name='name', caption=_('Name')),
        TableCol(name='abbr', caption=_('Abbr')),
        TableCol(name='year', caption=_('Year')),
        TableCol(name='trend', caption=_('Trend')),
        TableCol(name='lesson_duration', caption=_('Lesson duration')),
    ]
    view_fields = ['name', 'year', 'abbr', 'trendID', 'lessonDuration']
    item_tabs = [
        TopicsItemTab(), PlanTransferItemTab(),
        CustomerTariffItemTab(), TeacherTariffItemTab()
        ]

    def __init__(self):
        LookupController.__init__(self,
            data_source=TableLookupDataSource('plan_lookup'),
            columns=self.lookup_columns,
            mass_actions_class=self.model_object,
            title=self.model_object.model_title,
        )
        CRUDController.__init__(self, model_object=self.model_object)

exposed = PlanController()
